package com.study.common.baidu.map;

import com.study.common.baidu.map.domain.LbsVo;
import com.study.common.constant.Constants;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@Data
public class BaiduLbs {

    private static final String API_URLS = "https://api.map.baidu.com/geoconv/v1/";

    @Value("${map.baidu.api.url}")
    private String API_URL;

    @Value("${map.baidu.api.language.url}")
    private String API_LANGUAGE_URL;

    @Value("${map.baidu.api.key}")
    private String API_KEY ;

    private String DEFALT_LANGUAGE = "local";

    @Value("${map.baidu.api.languages}")
    private String languages;

    @Autowired
    private RestTemplate restTemplate;

    //多国语言
    public static Map<String,String> langsMap = new HashMap<String, String>();

    @PostConstruct
    public  void init() throws IOException {

        if(StringUtils.isNotBlank(languages)) {

            String [] ls = languages.split(",");

            for (String s : ls) {
                langsMap.put(s, s);
            }
        }

    }


    public String getLanguage(String language) {

        try {

            if (StringUtils.isBlank(language)) {
                language = DEFALT_LANGUAGE;
            }

            language = language.replace("_", "-");

            if (langsMap.containsKey(language)) {
                return langsMap.get(language);
            } else {

                String l = language.split("_")[0];
                if (langsMap.containsKey(l)) {
                    return langsMap.get(l);
                }

                return DEFALT_LANGUAGE;
            }

        } catch (Exception e) {
            return DEFALT_LANGUAGE;
        }

    }

    /**
     *
     * @Title: getBaiduAddressLanguage
     * @Description: 百度api物理地址转换 -- 新方法，支持多国语言
     * @author: 许智皓
     * @date: 2019年12月16日 下午4:23:12
     * @version: V1.0
     * @param lng
     * @param lat
     * @param language
     * @return String
     *
     * @updateDate:
     * @update:
     */
    public LbsVo getBaiduAddressLanguage(Double lng, Double lat, String language) {
        String address = Constants.STR_NULL;
        String locality = Constants.STR_NULL;

        try {

            language = getLanguage(language);

            /*
             * coordtype:
             * bd09ll（百度经纬度坐标）
             * bd09mc（百度墨卡托坐标）
             * gcj02（经国测局加密的坐标)
             * wgs84（gps获取的原始坐标）
             */
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(API_LANGUAGE_URL);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("ak", API_KEY));
            params.add(new BasicNameValuePair("output", "json"));
            params.add(new BasicNameValuePair("coordtype", "wgs84"));
            params.add(new BasicNameValuePair("extensions_poi","1"));
            params.add(new BasicNameValuePair("language", language));
            params.add(new BasicNameValuePair("location", lat + "," + lng));

            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(urlEncodedFormEntity);

            // 请求内容
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String json = EntityUtils.toString(entity).trim();
            if (StringUtils.isNotBlank(json)) {
                JSONObject obj = JSONObject.fromObject(json);
                Integer status = obj.getInt("status");
                if (status == 0) {
                    JSONObject addrObj = obj.getJSONObject("result");
                    address = addrObj.getString("formatted_address");
                } else {
                    log.error("BaiduLbs.getDaiBuAddress.error={}", obj);
                }
            }

        } catch (Exception e) {
            log.error("BaiduLbs.getDaiBuAddress.error={}", e);
        }
        LbsVo dto = new LbsVo();
        dto.setFormattedAddress(address);
        return dto;
    }


    /**
     *
     * @Title: getBaiduAddressLanguage
     * @Description: 百度api转经纬度
     * @author: 许智皓
     * @date: 2019年12月16日 下午4:23:12
     * @version: V1.0
     * @param lng
     * @param lat
     * @return String
     *
     * @updateDate:
     * @update:
     */
    public LbsVo getBaiduLatLng(Double lng, Double lat) {

        Double Lat = 0.00;
        Double Lng = 0.00;

        try {
            /**
             * from
             * 源坐标类型：
             * 1：GPS标准坐标；
             * 2：搜狗地图坐标；
             * 3：火星坐标（gcj02），即高德地图、腾讯地图和MapABC等地图使用的坐标；
             * 4：3中列举的地图坐标对应的墨卡托平面坐标;
             * 5：百度地图采用的经纬度坐标（bd09ll）；
             * 6：百度地图采用的墨卡托平面坐标（bd09mc）;
             * 7：图吧地图坐标；
             * 8：51地图坐标；
             */


            /**
             * to
             * 目标坐标类型：
             * 3：火星坐标（gcj02），即高德地图、腾讯地图及MapABC等地图使用的坐标；
             * 5：百度地图采用的经纬度坐标（bd09ll）；
             * 6：百度地图采用的墨卡托平面坐标（bd09mc）；
             */

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(API_URLS);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("ak", API_KEY));
            params.add(new BasicNameValuePair("coords", lng + "," + lat));
            params.add(new BasicNameValuePair("from", "1"));
            params.add(new BasicNameValuePair("to", "5"));

            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(urlEncodedFormEntity);

            // 请求内容
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String json = EntityUtils.toString(entity).trim();
            if (StringUtils.isNotBlank(json)) {
                JSONObject obj = JSONObject.fromObject(json);
                Integer status = obj.getInt("status");
                if (status == 0) {
                    JSONArray resultArray = obj.getJSONArray("result");
                    if (resultArray != null && resultArray.size() > 0) {
                        JSONObject resultObj = resultArray.getJSONObject(0);
                        Lng = resultObj.getDouble("x");
                        Lat = resultObj.getDouble("y");
                    }
                } else {
                    log.error("BaiduLbs.getDaiBuAddress.error={}", obj);
                }
            }

        } catch (Exception e) {
            log.error("BaiduLbs.getDaiBuAddress.error={}", e);
        }
        LbsVo dto = new LbsVo();
        dto.setLng(Lng);
        dto.setLat(Lat);
        return dto;
    }




    public LbsVo getBaiduAddressInfo(Double lng,Double lat,String language){
        String address = Constants.STR_NULL;
        String locality = Constants.STR_NULL;

        try {
            language = getLanguage(language);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            // 构造请求参数
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("ak", API_KEY));
            params.add(new BasicNameValuePair("output", "json"));
            params.add(new BasicNameValuePair("coordtype", "wgs84"));
            params.add(new BasicNameValuePair("extensions_poi","1"));
            params.add(new BasicNameValuePair("language", language));
            params.add(new BasicNameValuePair("location", lat + "," + lng));

            // 将参数编码为URL字符串
            String paramString = URLEncodedUtils.format(params, "UTF-8");

            // 构造请求URL
            String url = API_LANGUAGE_URL + "?" + paramString;

            // 发送Get请求
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            String json = response.getBody();

            if (StringUtils.isNotBlank(json)) {
                JSONObject obj = JSONObject.fromObject(json);
                Integer status = obj.getInt("status");
                if (status == 0) {
                    JSONObject addrObj = obj.getJSONObject("result");
                    address = addrObj.getString("formatted_address");

                } else {
                    log.error("BaiduLbs.getDaiBuAddress.error={}", obj);
                }
            }

        } catch (Exception e) {
            log.error("BaiduLbs.getDaiBuAddress.error={}", e);
        }

        LbsVo dto = new LbsVo();
        dto.setFormattedAddress(address);
        return dto;

    }

    /**
     * 百度api省份地址转换
     * 经纬度转换地址
     * @param lng 经度
     * @param lat 纬度
     * @return 物理地址
     */
    public JSONObject getBaiduAddressComponent(Double lng, Double lat) {

        JSONObject addrObj = null;

        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(API_URL);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("ak", API_KEY));
            params.add(new BasicNameValuePair("coordtype", "wgs84ll"));
            params.add(new BasicNameValuePair("pois", "0"));
            params.add(new BasicNameValuePair("location", lat + "," + lng));
            params.add(new BasicNameValuePair("output", "json"));
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(params, "UTF-8");
            httpPost.setEntity(urlEncodedFormEntity);
            // 请求内容
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String json = EntityUtils.toString(entity).trim();
            if (StringUtils.isNotBlank(json)) {
                JSONObject obj = JSONObject.fromObject(json);
                Integer status = obj.getInt("status");
                if (status == 0) {
                    addrObj = obj.getJSONObject("result").getJSONObject("addressComponent");
                }
            }
        } catch (Exception e) {
            log.error("getDaiBuAddress request baidu map error, exception:{}", e);
        }
        return addrObj;
    }


}

